é«éå颿°ãçšããé«åºŠãªãžã§ããªãã¯ããã°ã©ãã³ã°æè¡ãæ¢æ±ãã匷åãªæœè±¡åãšåå®å šãªã³ãŒããå®çŸããŸãã
é«åºŠãªãžã§ããªãã¯ãã¿ãŒã³ïŒé«éå颿°
ãžã§ããªãã¯ããã°ã©ãã³ã°ã«ãããåå®å šæ§ãç ç²ã«ããããšãªããããŸããŸãªåã«å¯ŸããŠåäœããã³ãŒããèšè¿°ã§ããŸããåºæ¬çãªãžã§ããªã¯ã¹ã匷åã§ãããé«éå颿°ã¯ããã«é«ã衚çŸåãè§£ãæŸã¡ãè€éãªåæäœãšåŒ·åãªæœè±¡åãå¯èœã«ããŸãããã®ããã°èšäºã§ã¯ãé«éå颿°ã®æŠå¿µãæãäžãããã®èœåãæ¢ããå®è·µçãªäŸãæäŸããŸãã
é«éå颿°ãšã¯ïŒ
æ¬è³ªçã«ãé«éå颿°ãšã¯ãå¥ã®åãåŒæ°ãšããŠåãåããæ°ããåãè¿ãåã®ããšã§ããå€ã§ã¯ãªãåã«å¯ŸããŠæäœãè¡ã颿°ã ãšèããŠãã ããããã®æ©èœã«ãããä»ã®åã«äŸåããåãæŽç·Žãããæ¹æ³ã§å®çŸ©ããéãéãããããåå©çšå¯èœã§ä¿å®æ§ã®é«ãã³ãŒãã«ã€ãªãããŸããããã¯ãžã§ããªã¯ã¹ã®åºæ¬çãªèãæ¹ãåã¬ãã«ã§çºå±ããããã®ã§ãããã®åã¯ãæã ãå®çŸ©ããã«ãŒã«ã«åŸã£ãŠåã倿ããèœåã«ç±æ¥ããŸãã
ãããããããçè§£ããããã«ãéåžžã®ãžã§ããªã¯ã¹ãšæ¯èŒããŠã¿ãŸããããå žåçãªãžã§ããªãã¯åã¯æ¬¡ã®ããã«ãªããŸãïŒãããã®æŠå¿µãããŸã説æã§ããå ç¢ãªåã·ã¹ãã ãæã€èšèªã§ããTypeScriptã®æ§æã䜿çšããŸãïŒïŒ
interface Box<T> {
value: T;
}
ããã§ã`Box<T>` ã¯ãžã§ããªãã¯åã§ããã`T` ã¯åãã©ã¡ãŒã¿ã§ãã`Box<number>` ã `Box<string>` ã®ããã«ãä»»æã®åã® `Box` ãäœæã§ããŸããããã¯äžæ¬¡ã®ãžã§ããªãã¯ã§ãããå ·äœçãªåãçŽæ¥æ±ããŸããé«éå颿°ã¯ãå颿°ããã©ã¡ãŒã¿ãšããŠåãå ¥ããããšã§ããããããã«äžæ©é²ããŸãã
ãªãé«éå颿°ã䜿çšããã®ãïŒ
é«éå颿°ã«ã¯ããã€ãã®å©ç¹ããããŸãïŒ
- ã³ãŒãã®åå©çšæ§ïŒ ããŸããŸãªåã«é©çšã§ããæ±çšçãªå€æãå®çŸ©ããã³ãŒãã®éè€ãæžãããŸãã
- æœè±¡åïŒ è€éãªåããžãã¯ãã·ã³ãã«ãªã€ã³ã¿ãŒãã§ãŒã¹ã®èåŸã«é ããã³ãŒãã®çè§£ãšä¿å®ã容æã«ããŸãã
- åå®å šæ§ïŒ ã³ã³ãã€ã«æã«åã®æ£ãããä¿èšŒããæ©æã«ãšã©ãŒãæ€åºããå®è¡æã®äºæãã¬äºæ ãé²ããŸãã
- 衚çŸåïŒ åéã®è€éãªé¢ä¿ãã¢ãã«åããããæŽç·Žãããåã·ã¹ãã ãå¯èœã«ããŸãã
- æ§æå¯èœæ§ïŒ æ¢åã®å颿°ãçµã¿åãããŠæ°ããå颿°ãäœæããããåçŽãªéšåããè€éãªå€æãæ§ç¯ããŸãã
TypeScriptã§ã®äŸ
é«åºŠãªåã·ã¹ãã æ©èœã«å¯ŸããŠåªãããµããŒããæäŸããèšèªã§ããTypeScriptã䜿çšããå®è·µçãªäŸãããã€ãèŠãŠãããŸãããã
äŸ1ïŒããããã£ãReadonlyã«ãããã³ã°ãã
æ¢åã®åã®ãã¹ãŠã®ããããã£ã `readonly` ãšããŠããŒã¯ãããæ°ããåãäœæãããã·ããªãªãèããŠã¿ãŸããããé«éå颿°ããªããã°ãå ã®åããšã«æ°ããåãæåã§å®çŸ©ããå¿ èŠããããããããŸãããé«éå颿°ã¯åå©çšå¯èœãªè§£æ±ºçãæäŸããŸãã
type Readonly<T> = {
readonly [K in keyof T]: T[K];
};
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = Readonly<Person>; // All properties of Person are now readonly
ãã®äŸã§ã¯ã`Readonly<T>` ãé«éå颿°ã§ããããã¯å `T` ãå ¥åãšããŠåãåãããã¹ãŠã®ããããã£ã `readonly` ã§ããæ°ããåãè¿ããŸããããã¯TypeScriptã®ãããåïŒmapped typesïŒæ©èœã䜿çšããŠããŸãã
äŸ2ïŒæ¡ä»¶ä»ãã®å
æ¡ä»¶ä»ãã®åã䜿çšãããšãæ¡ä»¶ã«äŸåããåãå®çŸ©ã§ããŸããããã«ãããæã ã®åã·ã¹ãã ã®è¡šçŸåãããã«åäžããŸãã
type IsString<T> = T extends string ? true : false;
// Usage
type Result1 = IsString<string>; // true
type Result2 = IsString<number>; // false
`IsString<T>` 㯠`T` ãæååã§ãããã©ããããã§ãã¯ããŸããããããã§ããã° `true` ãè¿ããããã§ãªããã° `false` ãè¿ããŸãããã®åã¯åã¬ãã«ã§é¢æ°ãšããŠæ©èœããåãåãåã£ãŠããŒã«åãçæããŸãã
äŸ3ïŒé¢æ°ã®æ»ãå€ã®åãæœåºãã
TypeScriptã«ã¯ `ReturnType<T>` ãšããçµã¿èŸŒã¿ã®ãŠãŒãã£ãªãã£åããããããã¯é¢æ°åã®æ»ãå€ã®åãæœåºããŸãããããã©ã®ããã«æ©èœããæŠå¿µçã«é¡äŒŒãããã®ãã©ã®ããã«å®çŸ©ã§ããããèŠãŠã¿ãŸãããïŒ
type MyReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
function greet(name: string): string {
return `Hello, ${name}!`;
}
type GreetReturnType = MyReturnType<typeof greet>; // string
ããã§ã`MyReturnType<T>` 㯠`infer R` ã䜿çšããŠé¢æ°å `T` ã®æ»ãå€ã®åããã£ããã£ãããããè¿ããŸããããã¯ã颿°åã«å¯ŸããŠæäœãè¡ããããããæ å ±ãæœåºããããšã«ãã£ãŠãå颿°ã®é«éçãªæ§è³ªãåã³ç€ºããŠããŸãã
äŸ4ïŒåã«ãããªããžã§ã¯ãããããã£ã®ãã£ã«ã¿ãªã³ã°
æ¢åã®ãªããžã§ã¯ãåããç¹å®ã®åã®ããããã£ã®ã¿ãå«ãæ°ããåãäœæããããšæ³åããŠã¿ãŠãã ãããããã¯ããããåãæ¡ä»¶ä»ãã®åãããã³ããŒã®åãããã³ã°ã䜿çšããŠå®çŸã§ããŸãïŒ
type FilterByType<T, U> = {
[K in keyof T as T[K] extends U ? K : never]: T[K];
};
interface Example {
name: string;
age: number;
isValid: boolean;
}
type StringProperties = FilterByType<Example, string>; // { name: string }
ãã®äŸã§ã¯ã`FilterByType<T, U>` ã¯2ã€ã®åãã©ã¡ãŒã¿ãåããŸãïŒ`T`ïŒãã£ã«ã¿ãªã³ã°ãããªããžã§ã¯ãåïŒãš `U`ïŒãã£ã«ã¿ãªã³ã°åºæºãšãªãåïŒããããå㯠`T` ã®ããŒãå埩åŠçããŸããæ¡ä»¶ä»ãã®å `T[K] extends U ? K : never` ã¯ãã㌠`K` ã®ããããã£ã®åã `U` ãç¶æ¿ããŠãããã©ããããã§ãã¯ããŸããããããã§ããã°ã㌠`K` ã¯ä¿æãããããã§ãªããã° `never` ã«ããããããçµæã®åããããããã£ã广çã«åé€ãããŸãããã®åŸããã£ã«ã¿ãªã³ã°ããããªããžã§ã¯ãåãæ®ãã®ããããã£ã§æ§ç¯ãããŸããããã¯ãåã·ã¹ãã ã®ããè€éãªçžäºäœçšã瀺ããŠããŸãã
é«åºŠãªæŠå¿µ
åã¬ãã«é¢æ°ãšèšç®
æ¡ä»¶ä»ãã®åãååž°çãªåãšã€ãªã¢ã¹ïŒäžéšã®èšèªã§å©çšå¯èœïŒã®ãããªé«åºŠãªåã·ã¹ãã æ©èœã䜿ãã°ãåã¬ãã«ã§èšç®ãå®è¡ããããšãå¯èœã§ããããã«ãããåã«å¯ŸããŠæäœãè¡ãè€éãªããžãã¯ãå®çŸ©ãã广çã«åã¬ãã«ã®ããã°ã©ã ãäœæã§ããŸããå€ã¬ãã«ã®ããã°ã©ã ãšæ¯èŒãããšèšç®èœåã«éãã¯ãããŸãããåã¬ãã«ã®èšç®ã¯ãè€éãªäžå€æ¡ä»¶ã匷å¶ããããæŽç·Žãããå倿ãå®è¡ãããããäžã§äŸ¡å€ããããŸãã
å¯å€é·ã«ã€ã³ãã®æäœ
äžéšã®åã·ã¹ãã ãç¹ã«Haskellã®åœ±é¿ãåããèšèªã§ã¯ãå¯å€é·ã«ã€ã³ãïŒé«ã«ã€ã³ãåãšããŠãç¥ãããïŒããµããŒãããŠããŸããããã¯ãåã³ã³ã¹ãã©ã¯ã¿ïŒ`Box`ãªã©ïŒèªäœããåŒæ°ãšããŠåã³ã³ã¹ãã©ã¯ã¿ãåãããšãã§ããããšãæå³ããŸããããã«ãããç¹ã«é¢æ°åããã°ã©ãã³ã°ã®æèã«ãããŠãããã«é«åºŠãªæœè±¡åã®å¯èœæ§ãéãããŸããScalaã®ãããªèšèªããã®ãããªæ©èœãæäŸããŠããŸãã
å šäœçãªèæ ®äºé
é«åºŠãªåã·ã¹ãã æ©èœã䜿çšããéã«ã¯ã以äžã®ç¹ãèæ ®ããããšãéèŠã§ãïŒ
- è€éãïŒ é«åºŠãªæ©èœã®é床ã®äœ¿çšã¯ãã³ãŒãã®çè§£ãšä¿å®ãå°é£ã«ããå¯èœæ§ããããŸãã衚çŸåãšå¯èªæ§ã®ãã©ã³ã¹ãç®æããŠãã ããã
- èšèªãµããŒãïŒ ãã¹ãŠã®èšèªãåãã¬ãã«ã§é«åºŠãªåã·ã¹ãã æ©èœããµããŒãããŠããããã§ã¯ãããŸãããããŒãºã«åã£ãèšèªãéžæããŠãã ããã
- ããŒã ã®å°éç¥èïŒ ããŒã ãé«åºŠãªåã·ã¹ãã æ©èœã䜿çšããã³ãŒãã䜿ãããªããä¿å®ããããã«å¿ èŠãªå°éç¥èãæã£ãŠããããšã確èªããŠãã ããããã¬ãŒãã³ã°ãã¡ã³ã¿ãŒã·ãããå¿ èŠã«ãªãå ŽåããããŸãã
- ã³ã³ãã€ã«æã®ããã©ãŒãã³ã¹ïŒ è€éãªåèšç®ã¯ã³ã³ãã€ã«æéãå¢å ãããå¯èœæ§ããããŸããããã©ãŒãã³ã¹ãžã®åœ±é¿ã«æ³šæããŠãã ããã
- ãšã©ãŒã¡ãã»ãŒãžïŒ è€éãªåãšã©ãŒã¯è§£èªãé£ããããšããããŸããåãšã©ãŒã广çã«çè§£ãããããã°ããã®ã«åœ¹ç«ã€ããŒã«ãæè¡ã«æè³ããŠãã ããã
ãã¹ããã©ã¯ãã£ã¹
- åãææžåããïŒ å颿°ã®ç®çãšäœ¿ç𿹿³ãæç¢ºã«èª¬æããŠãã ããã
- æå³ã®ããååã䜿çšããïŒ åãã©ã¡ãŒã¿ãåãšã€ãªã¢ã¹ã«ã¯ã説æçãªååãéžæããŠãã ããã
- ã·ã³ãã«ã«ä¿ã€ïŒ äžå¿ èŠãªè€éããé¿ããŠãã ããã
- åããã¹ãããïŒ å颿°ãæåŸ ã©ããã«åäœããããšã確èªããããã«ãåäœãã¹ããèšè¿°ããŠãã ããã
- ãªã³ã¿ãŒãšåãã§ãã«ãŒã䜿çšããïŒ ã³ãŒãã£ã³ã°æšæºã匷å¶ããæ©æã«åãšã©ãŒãæ€åºããŠãã ããã
çµè«
é«éå颿°ã¯ãåå®å šã§åå©çšå¯èœãªã³ãŒããèšè¿°ããããã®åŒ·åãªããŒã«ã§ãããããã®é«åºŠãªæè¡ãçè§£ãé©çšããããšã§ãããå ç¢ã§ä¿å®æ§ã®é«ããœãããŠã§ã¢ãäœæã§ããŸããè€éããå°å ¥ããå¯èœæ§ã¯ãããŸãããã³ãŒãã®æçæ§ãšãšã©ãŒé²æ¢ã®èгç¹ããã®å©ç¹ã¯ãå€ãã®å Žåãã³ã¹ããäžåããŸããåã·ã¹ãã ãé²åãç¶ããã«ã€ããŠãé«éå颿°ã¯ãç¹ã«TypeScriptãScalaãHaskellã®ãããªåŒ·åãªåã·ã¹ãã ãæã€èšèªã«ãããŠããœãããŠã§ã¢éçºã§ãŸããŸãéèŠãªåœ¹å²ãæããããšã«ãªãã§ãããããããã®æŠå¿µããããžã§ã¯ãã§è©Šãããã®æœåšèœåãæå€§éã«åŒãåºããŠãã ãããé«åºŠãªæ©èœã䜿çšããå Žåã§ããã³ãŒãã®å¯èªæ§ãšä¿å®æ§ãåªå ããããšãå¿ããªãã§ãã ããã